#ifndef  __EB_CLOCK_H__
#define  __EB_CLOCK_H__

#include <types.h>
#include <kernel/syslog.h>
#include <string.h>
#include <kernel/fdt.h>


struct clock_node;


struct clock_ops {
    int (*enable)(struct clock_node *clock, size_t flag);
    int (*disable)(struct clock_node *clock, size_t flag);
    int (*set_freq)(struct clock_node *clock, size_t freq);
};


typedef struct clock_node {
    list_node_t link;
    const char *name;
    size_t      reg;
    size_t      freq;
    size_t      status;
    struct clock_ops *ops;
}clock_node_t;


#define  CLOCK_SYSLOG_INFO(...)   SYSLOG_INFO("CLOCK: "__VA_ARGS__)
#define  CLOCK_SYSLOG_ERROR(...)  SYSLOG_ERROR("CLOCK: "__VA_ARGS__)
#define  CLOCK_SYSLOG_WARN(...)   SYSLOG_WARN("CLOCK: "__VA_ARGS__)
#define  CLOCK_DEBUG_TRACE(...)   DEBUG_TRACE("CLOCK: "__VA_ARGS__)


/**
 * @brief get clock list head
 * @param none
 * @return list head
 */
list_node_t* clock_get_list_head(void);


/**
 * @brief add clock node to list
 * @param clock: clock node
 * @return none
 */
void clock_node_add(struct clock_node *clock);


/**
 * @brief find clock node by name
 * @param name: clock name
 * @return clock node
 */
struct clock_node* clock_find_by_name(const char *name);


/**
 * @brief enable clock
 * @param clock: clock node
 * @param flag: flag
 * @return none
 */
void clock_enable(struct clock_node *clock, size_t flag);


/**
 * @brief disable clock
 * @param clock: clock node
 * @param flag: flag
 * @return none
 */
void clock_disable(struct clock_node *clock, size_t flag);


/**
 * @brief enable clock by name
 * @param name: clock name
 * @param flag: flag
 * @return none
 */
void clock_enable_by_name(const char *name, size_t flag);


/**
 * @brief disable clock by name
 * @param name: clock name
 * @param flag: flag
 * @return none
 */
void clock_disable_by_name(const char *name, size_t flag);


/**
 * @brief set clock frequency
 * @param clock: clock node
 * @param freq: frequency
 * @return none
 */
void clock_set_freq(struct clock_node *clock, size_t freq);


/**
 * @brief get clock frequency
 * @param clock: clock node
 * @return frequency
 */
size_t clock_get_freq(struct clock_node *clock);


/**
 * @brief set clock frequency by name
 * @param name: clock name
 * @param freq: frequency
 * @return none
 */
void clock_set_freq_by_name(const char *name, size_t freq);


/**
 * @brief get clock frequency by name
 * @param name: clock name
 * @return frequency
 */
size_t clock_get_freq_by_name(const char *name);


#endif //!__EB_CLOCK_H__